package com.sdk.pay.transfer.services;

import android.accessibilityservice.AccessibilityService;
import android.annotation.TargetApi;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import com.sdk.pay.transfer.MainActivity;
import com.sdk.pay.transfer.constant.PayContext;
import com.sdk.pay.transfer.model.WECHATBean;
import com.sdk.pay.transfer.provider.ProviderHelper;
import com.sdk.pay.transfer.utils.ActivityHelper;
import com.sdk.pay.transfer.utils.UploadDataUtil;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import static com.sdk.pay.transfer.constant.WechatConstants.CLEAR_MONEY;
import static com.sdk.pay.transfer.constant.WechatConstants.CONFIRM;
import static com.sdk.pay.transfer.constant.WechatConstants.SET_MONEY;
import static com.sdk.pay.transfer.constant.WechatConstants.WECHAT_ACTIVITY_PERSON_CENTER;
import static com.sdk.pay.transfer.constant.WechatConstants.WECHAT_ADD_REMAEK;
import static com.sdk.pay.transfer.constant.WechatConstants.WECHAT_COLLECT_MAINUI;
import static com.sdk.pay.transfer.constant.WechatConstants.WECHAT_CREATE_CODEUI;
import static com.sdk.pay.transfer.constant.WechatConstants.WECHAT_CREATE_CODEUI_DIALOG;
import static com.sdk.pay.transfer.constant.WechatConstants.WECHAT_PACKAGE_NAME;

/**
 * Created by Administrator on 2017/9/6.
 */

public class WechatAccessibilityService extends AccessibilityService {
    private static OutputStream os;
    private static int mCurrent = 0;
    private WECHATBean bean;

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        // 获取当前事件的包名
        String nowPackageName = event.getPackageName().toString();
        // 判断是否为微信应用、并判断当前状态是否为运行状态
        if (nowPackageName.equals(WECHAT_PACKAGE_NAME)) {
//            MainActivity.instance.log("event.toString : " + event.toString());
            // 获取事件活动的窗口布局根节点
            switch (event.getEventType()) {
                case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
                    String className = event.getClassName().toString();
                    //微信二维码设置金额及添加备注界面
                    switch (className) {
                        case WECHAT_COLLECT_MAINUI:
                            checkUI();
                            break;
                        case WECHAT_CREATE_CODEUI:
                            createQrCode();
                            break;
                        case WECHAT_CREATE_CODEUI_DIALOG:
                            setDescInDialog();
                            break;
                        case WECHAT_ACTIVITY_PERSON_CENTER:
                            verifyAccount();
                            break;
                    }
                    break;
            }
        }
    }

    private void verifyAccount() {
        AccessibilityNodeInfo rootNode = this.getRootInActiveWindow();
        if (rootNode == null || PayContext.VerifyWechat != 1) {
            return;
        }
        List<AccessibilityNodeInfo> list = rootNode.
                findAccessibilityNodeInfosByViewId
                        ("android:id/summary");
        if (list.size() > 0) {
            boolean flag = false;
            for (AccessibilityNodeInfo info : list) {
                if (!flag)
                    flag = info.getText().toString().equals(PayContext.VerifyAliAccout);
            }
            PayContext.VerifyAliResult = flag;
            PayContext.VerifyWechat = 2;
            MainActivity.instance.log("微信验证结果: " + PayContext.VerifyAliResult);
            List<AccessibilityNodeInfo> back = getRootInActiveWindow()
                    .findAccessibilityNodeInfosByViewId("com.tencent.mm:id/hg");
            // 点击返回上一界面
            if (back.size() >= 1) {
                clickButton(back.get(0));
                ActivityHelper.startProductQRActivity();
            }
        }
    }

    private WECHATBean getBean() {
        return ProviderHelper.get_OneBean_Without_CodeUrl(this);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    private void createQrCode() {
        bean = getBean();
        if (bean == null) {
            List<AccessibilityNodeInfo> list = getRootInActiveWindow()
                    .findAccessibilityNodeInfosByViewId("com.tencent.mm:id/hg");
            // 点击返回上一界面
            if (list.size() >= 1) {
                clickButton(list.get(0));
            }
            return;
        }

        //设置备注
        if (clickViewByContent(WECHAT_ADD_REMAEK)) {
            return;
        }
        //设置金额
        setMoney(getRootInActiveWindow());
        //输入金额和备注完毕点击确定
        clickViewByContent(CONFIRM);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void checkUI() {
        WECHATBean bean = getBean();
        if (bean == null) {
            List<AccessibilityNodeInfo> list = getRootInActiveWindow()
                    .findAccessibilityNodeInfosByViewId("com.tencent.mm:id/hg");
            // 点击返回上一界面
            if (list.size() >= 1) {
                clickButton(list.get(0));
            }
            ActivityHelper.startProductQRActivity();
            MainActivity.instance.cleanParam();
            UploadDataUtil.getInstance().uploadDatasInOrder(this);
            return;
        }
        if (clickClearMoneyInCollectMainUi()) {
            return;
        }
        clickSetMoneyInCollectMainUi();
    }

    private void clickButton(AccessibilityNodeInfo info) {
        AccessibilityNodeInfo parent = info;
        while (parent != null) {
            if (parent.isClickable()) {
                // 模拟点击，跳出循环
                parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                break;
            }
            parent = parent.getParent();
        }
    }

    public static void startActivity(String packageName, String activityName) {
        String cmd = String.format("am start -n %s/%s", packageName,
                activityName);
        execRootCmd(cmd);
    }


    private boolean clickSetMoneyInCollectMainUi() {
        return clickViewByContentInCollectMainUi(SET_MONEY);
    }

    private boolean clickClearMoneyInCollectMainUi() {
        return clickViewByContentInCollectMainUi(CLEAR_MONEY);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private boolean clickViewByContentInCollectMainUi(String content) {
        return recycleInCollectMainUi(getRootInActiveWindow(), content);
    }

    public static final void exec(String cmd) {
        try {
            if (os == null) {
                os = Runtime.getRuntime().exec("su").getOutputStream();
            }
            os.write(cmd.getBytes());
            os.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static final void click(String x, String y) {
        exec(String.format("input tap %s %s \n", x, y));
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void setDescInDialog() {
        setDesc(getRootInActiveWindow());
        clickViewByContent(CONFIRM);
    }

    private AccessibilityNodeInfo setDesc(AccessibilityNodeInfo node) {
        if (node == null) {
            return node;
        }
        if (node.getChildCount() == 0) {
            String string = node.getClassName().toString();
            if (string.contains("EditText")) {
                if (bean != null) {
                    setContent(node, bean.getReason());
                }
                return node;
            }
        } else {
            for (int i = 0; i < node.getChildCount(); i++) {
                if (node.getChild(i) != null) {
                    setDesc(node.getChild(i));
                }
            }
        }
        return node;
    }

    private AccessibilityNodeInfo setMoney(AccessibilityNodeInfo node) {
        if (node == null) {
            return node;
        }
        if (node.getChildCount() == 0) {
            if (node.getText() != null) {
                String string = node.getClassName().toString();
                if (string.contains("EditText")) {
                    if (bean != null) {
                        setContent(node, bean.getMoney());
                    }
                    return node;
                }
            }
        } else {
            for (int i = 0; i < node.getChildCount(); i++) {
                if (node.getChild(i) != null) {
                    setMoney(node.getChild(i));
                }
            }
        }
        return node;
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void setContent(AccessibilityNodeInfo info, String content) {
        Bundle arguments = new Bundle();
        arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, content);
        info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
    }

    private void clipboardPaste(String lable, String text,
                                AccessibilityNodeInfo info) {
        ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
        ClipData clipData = ClipData.newPlainText(lable, text);
        clipboardManager.setPrimaryClip(clipData);
        // 模拟粘贴
        info.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
        info.performAction(AccessibilityNodeInfo.ACTION_PASTE);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private boolean clickViewByContent(String content) {
        return recycle(getRootInActiveWindow(), content);
    }

    private boolean recycle(AccessibilityNodeInfo node, String content) {
        if (node == null) {
            return false;
        }
        if (node.getChildCount() == 0) {
            if (node.getText() != null) {
                String string = node.getText().toString();
                if (string.contains(content)) {
                    AccessibilityNodeInfo parent = node;
                    while (parent != null) {
                        if (parent.isClickable()) {
                            parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                            break;
                        }
                        parent = parent.getParent();
                    }
                    return true;
                }
            }
        } else {
            for (int i = 0; i < node.getChildCount(); i++) {
                if (node.getChild(i) != null) {
                    boolean recycle = recycle(node.getChild(i), content);
                    if (recycle) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private boolean recycleInCollectMainUi(AccessibilityNodeInfo node, String content) {
        if (node == null) {
            return false;
        }
        if (node.getChildCount() == 0) {
            if (node.getText() != null) {
                String string = node.getText().toString();
                if (string.contains(content)) {
                    AccessibilityNodeInfo parent = node;
                    while (parent != null) {
                        if (parent.isClickable()) {
                            Rect outBounds = new Rect();
                            parent.getBoundsInScreen(outBounds);
                            click(String.valueOf((outBounds.left + outBounds.right) / 2),
                                    String.valueOf((outBounds.top + outBounds.bottom) / 2));
                            if (content.equals(CLEAR_MONEY)) {
                                Timer timer = new Timer();
                                timer.schedule(new TimerTask() {
                                    @Override
                                    public void run() {
                                        clickSetMoneyInCollectMainUi();
                                    }
                                }, 1100);
                            }
                            break;
                        }
                        parent = parent.getParent();
                    }
                    return true;
                }
            }
        } else {
            for (int i = 0; i < node.getChildCount(); i++) {
                if (node.getChild(i) != null) {
                    boolean recycle = recycleInCollectMainUi(node.getChild(i), content);
                    if (recycle) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    @Override
    public void onInterrupt() {

    }

    public static String execRootCmd(String cmd) {
        String result = "";
        DataOutputStream dos = null;
        DataInputStream dis = null;

        try {
            Process p = Runtime.getRuntime().exec("su");// 经过Root处理的android系统即有su命令
            dos = new DataOutputStream(p.getOutputStream());
            dis = new DataInputStream(p.getInputStream());

//            MainActivity.instance.log(cmd);
            dos.writeBytes(cmd + "\n");
            dos.flush();
            dos.writeBytes("exit\n");
            dos.flush();
            String line = null;
            while ((line = dis.readLine()) != null) {
//                MainActivity.instance.log("result = " + line);
                result += line;
            }
            p.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (dis != null) {
                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
}